﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.IO;

namespace ExceptionManager
{
    // NOTE: Exception manager only gets used when you run without debugging

    // For instructions, visit http://www.kaycircle.com/CSharp-Excpetion-Manager-Block-and-Log-Unhandled-Exceptions

    public class ExceptionManager
    {
        public static void Setup()
        {
            if (Enabled)
            {

                Application.Current.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(Current_DispatcherUnhandledException);
            }

        }

        protected static bool _Enabled = true;

        public static bool Enabled
        {
            get
            {
                return _Enabled;
            }

            set
            {
                _Enabled = value;
            }
        }

        protected static bool _IsShowingDialog = true;

        public static bool ShowDialog
        {
            get
            {
                return _IsShowingDialog;
            }
            set
            {
                _IsShowingDialog = value;
            }
        }

        public static string LogPath
        {
            get
            {
                return GetAppDir() + "error_log.txt";
            }
        }

        public static void LogException(Exception ex, bool innerException)
        {
            try
            {
                string prepend = "";

                if (innerException)
                {
                    prepend = ">>>>>>>> ";
                }

                StreamWriter writer = new StreamWriter(LogPath, true);
                writer.WriteLine(prepend + "==================================================================================");
                writer.WriteLine(prepend + "Timestamp: '" + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString() + "'");
                writer.WriteLine(prepend + "Exception: '" + ex.GetType().Name + "'");
                writer.WriteLine(prepend + "Message: '" + ex.Message + "'");
                writer.WriteLine(prepend + "Source: '" + ex.Source + "'");

                writer.WriteLine(prepend + "Stack Trace: ");
                writer.WriteLine(prepend + ex.StackTrace);



                writer.WriteLine(prepend + "==================================================================================");

                writer.Close();

                if (ex.InnerException != null)
                {
                    writer.WriteLine("Inner Exception: ");
                    LogException(ex.InnerException, true);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Serious error occurred!  Unable to append to log file!");
            }
        }

        public static string GetAppDir()
        {
            string ans = typeof(ExceptionManager).Assembly.Location;

            while (ans.Length > 0)
            {
                if (ans[ans.Length - 1] == '\\')
                    break;
                else
                    ans = ans.Substring(0, ans.Length - 1);
            }

            if (ans.Substring(ans.Length - 1, 1) != "\\")
                ans += "\\";

            return ans;
        }

        public static void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            string safeExceptions = "TargetInvocationException";

            if (!Enabled)
            {
                return;
            }

            LogException(e.Exception, false);

            if (safeExceptions.Contains(e.Exception.GetType().Name) || (e.Exception.GetType().Name.Contains(safeExceptions)))
            {
                e.Handled = true;
                return;
            }

            

            if (!ShowDialog)
            {
                e.Handled = true;
                return;
            }

            

            if (MessageBox.Show(e.Exception.Message + "\r\n\r\n" + e.Exception.StackTrace, "Unhandled Exception", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                e.Handled = true;
            }
            else
            {
                throw e.Exception;
            }
        }
    }
}
